#include<iostream>
#include<list>
#include<vector>
#include<unordered_set>
#include<functional>
#include<memory>
#include<unordered_map>
#include<cassert>
#include<unistd.h>

/*定时任务类*/
using OnTimerCallback = std::function<void()>;
using ReleaseCallback = std::function<void()>;

class Timer{
private:
    int _timeout; //当前定时器任务的延时时间
    bool _canceled; /*false任务正常执⾏,true 任务被取消*/
    uint64_t _timer_id;
    OnTimerCallback _timer_callback;
    ReleaseCallback _release_callback;
public:
    Timer(uint64_t timer_id, int timeout):_timer_id(timer_id),
    _timeout(timeout),_canceled(false){}
    ~Timer(){
        if(_release_callback) _release_callback();
        if(_timer_callback && !_canceled) _timer_callback();
    }
    uint64_t id();
    int delay_time() { return _timeout; }
    void canceled() { _canceled = true; }// 取消定时任务
    void set_on_time_callback(const OnTimerCallback &cb){
        _timer_callback = cb;
    }
    void set_release_callback(const ReleaseCallback &cb){
        _release_callback = cb;
    }
};

#define MAX_TIMEOUT 60
class TimerQueue{
private:
    using WeakTimer = std::weak_ptr<Timer>;
    using PtrTimer = std::shared_ptr<Timer>;
    using Bucket = std::vector<PtrTimer>;//单层时间轮
    using BucketList = std::vector<Bucket>;
    
    int _tick;
    int _capacity;

    BucketList _conns;
    std::unordered_map<uint64_t,WeakTimer> _timers;
public:
    TimerQueue():_tick(0),_capacity(MAX_TIMEOUT),_conns(_capacity)
    {
    }
    bool has_timer(uint64_t id){
        auto it = _timers.find(id);
        if(it != _timers.end()) return true;
        return false;
    }
    void timer_add(const OnTimerCallback &cb, int delay, uint64_t id){
        if(delay > _capacity || delay <= 0) return ;
        PtrTimer timer(new Timer (id,delay));
        timer->set_on_time_callback(cb);
        timer->set_release_callback(std::bind(&TimerQueue::remove_weaktimer_from_timequeue,this,id));
        _timers[id] = WeakTimer(timer);
        _conns[(_tick + delay)%_capacity].push_back(timer);
    }
    
    void timer_refresh(uint64_t id){
        auto it = _timers.find(id);
        assert(it != _timers.end()); //测试用断言
        int  delay = it->second.lock()->delay_time();
        _conns[(_tick+delay)%_capacity].push_back(PtrTimer(it->second));
    }
    
    void remove_weaktimer_from_timequeue(uint64_t id){
        auto it = _timers.find(id);
        if(it != _timers.end()){
            _timers.erase(it);
        }
    }

    void run_ontime_task(){
        _tick = (_tick+1)%_capacity;
        _conns[_tick].clear();
    }    
};

class TimerTest{
private:
    int _data;
public:
    TimerTest(int data):_data(data){
        std::cout<<"test 构造!\n";
    }
    ~TimerTest(){ std::cout<<" test 析构!\n"; }
};

void del(TimerTest *t){
    delete t;
}

int main(){
    TimerQueue tq;
    
    TimerTest *t = new TimerTest(10);
    
    int id = 3;
    
    tq.timer_add(std::bind(del,t),1,id);
    
    for(int i =0 ;i<5;i++){
        sleep(1);
        tq.run_ontime_task();
        tq.timer_refresh(id);//如果定时器是一秒的话，直接被刷新
        std::cout<<"刷新了一下3号定时任务!\n";
    }
    // std::cout<<"刷新定时任务停止，5s后是释放任务\n";
    int i=1;
    while(1){
        sleep(1);
        std::cout<<"____________第"<<i<<"秒\n";
        tq.run_ontime_task();
        if(tq.has_timer(id)==false){
            std::cout<<"定时任务已经被执行完毕!\n";
            break;
        }
        i++;
    }
    return 0;
}